﻿// Type: ICSharpCode.WinFormsUI.Controls.TreeGridCell
// Assembly: ExpandableGridView, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: 01AF7F03-14C8-403C-9988-D5C2B7E87D00
// Assembly location: C:\Users\lenovo\Desktop\TreeGridViewTest\TreeGridViewTest\lib\ExpandableGridView.dll

using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

namespace ICSharpCode.WinFormsUI.Controls
{
    public class TreeGridCell : DataGridViewTextBoxCell //DataGridViewTextBoxCell
    {
        private int _imageWidth = 0;
        private int _imageHeight = 0;
        private int _imageHeightOffset = 0;
        private const int INDENT_WIDTH = 20;
        private const int INDENT_MARGIN = 5;
        private int glyphWidth;
        private int calculatedLeftPadding;
        internal bool IsSited;
        internal bool IsChecked;
        internal bool IsCheckbox;
        private Padding _previousPadding;
        private Rectangle _lastKnownGlyphRect;

        public int Level
        {
            get
            {
                TreeGridNode owningNode = this.OwningNode;
                if (owningNode != null)
                    return owningNode.Level;
                else
                    return -1;
            }
        }

        protected virtual int GlyphMargin
        {
            get
            {
                return (this.Level - 1) * 20 + 5;
            }
        }

        protected virtual int GlyphOffset
        {
            get
            {
                return (this.Level - 1) * 20;
            }
        }

        public TreeGridNode OwningNode
        {
            get
            {
                return this.OwningRow as TreeGridNode;
            }
        }

        public TreeGridCell()
        {
            this.glyphWidth = 18;
            this.calculatedLeftPadding = 0;             
            this.IsSited = false;           
        }

        public override object Clone()
        {
            TreeGridCell treeGridCell = (TreeGridCell)base.Clone();
            treeGridCell.glyphWidth = this.glyphWidth;
            treeGridCell.calculatedLeftPadding = this.calculatedLeftPadding;
            return (object)treeGridCell;
        }

        protected internal virtual void UnSited()
        {
            this.IsSited = false;
            this.Style.Padding = this._previousPadding;
        }

        protected internal virtual void Sited()
        {
            this.IsSited = true;
            this._previousPadding = this.Style.Padding;
            this.UpdateStyle();
        }

        protected internal virtual void UpdateStyle()
        {
            if (!this.IsSited)
                return;
            int level = this.Level;
            Padding padding = this._previousPadding;
            Size preferredSize;
            using (Graphics graphics = this.OwningNode._grid.CreateGraphics())
                preferredSize = this.GetPreferredSize(graphics, this.InheritedStyle, this.RowIndex, new Size(0, 0));
            Image image = this.OwningNode.Image;
            if (image != null)
            {
                this._imageWidth = image.Width + 2;
                this._imageHeight = image.Height + 2;
            } 
            else
            {
                this._imageWidth = this.glyphWidth;
                this._imageHeight = 16;
            }
            if (preferredSize.Height < this._imageHeight)
            {
                this.Style.Padding = new Padding(padding.Left + level * 20 + this._imageWidth + 5, padding.Top + this._imageHeight / 2, padding.Right, padding.Bottom + this._imageHeight / 2);
                this._imageHeightOffset = 2;
            }
            else
                this.Style.Padding = new Padding(padding.Left + level * 20 + this._imageWidth + 5, padding.Top, padding.Right, padding.Bottom);
            this.calculatedLeftPadding = (level - 1) * this.glyphWidth + this._imageWidth + 5;
        }

        protected internal virtual Rectangle GetCheckboxBounds()
        {            
            TreeGridNode owningNode = this.OwningNode;

            Rectangle cellBounds = owningNode._grid.GetCellDisplayRectangle(this.ColumnIndex, this.RowIndex, true);
            Rectangle rectangle = new Rectangle(cellBounds.X + this.GlyphMargin, cellBounds.Y, 20, cellBounds.Height - 1);

            Point point = this._imageHeight <= cellBounds.Height ? new Point(rectangle.X + this.glyphWidth, cellBounds.Height / 2 - (this._imageHeight - 4) / 2 + cellBounds.Y) : new Point(rectangle.X + this.glyphWidth, cellBounds.Y + this._imageHeightOffset);
            Size size = new Size(this._imageWidth - 2, this._imageHeight - 2);

            return new Rectangle(point, size);
        }

        public bool Checked
        {
            get { return IsChecked; }
            set { IsChecked = value; }
        }

        public bool Checkbox
        {
            get { return IsCheckbox; }
            set
            {
                IsCheckbox = value;
            }
        }

        protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
        {
            TreeGridNode owningNode = this.OwningNode;           
            if (owningNode == null)
                return;

            IsCheckbox = owningNode.Checkbox;
            bool checkBoxes = owningNode._grid.CheckBoxes;
            Image image = owningNode.Image;
            if (this._imageHeight == 0 && image != null)
                this.UpdateStyle();                  
           
            base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts);

            Rectangle rectangle = new Rectangle(cellBounds.X + this.GlyphMargin, cellBounds.Y, 20, cellBounds.Height - 1);
            int num1 = rectangle.Width / 2;
            int level = this.Level;

            if (checkBoxes)
            {
                if (Checkbox)
                {
                    if (image == null)
                    {
                        Point point = this._imageHeight <= cellBounds.Height ? new Point(rectangle.X + this.glyphWidth, cellBounds.Height / 2 - (this._imageHeight - 2) / 2 + cellBounds.Y) : new Point(rectangle.X + this.glyphWidth, cellBounds.Y + this._imageHeightOffset);
                        Size size = new System.Drawing.Size(this._imageWidth - 2, this._imageHeight - 2);
                        Rectangle checkboxRect = new Rectangle(point, size);
                        GraphicsContainer container = graphics.BeginContainer();
                        graphics.SetClip(cellBounds);

                        if (this.IsChecked)
                            graphics.DrawImageUnscaled(ICSharpCode.WinFormsUI.Controls.Properties.Resources._checked, checkboxRect);
                        else
                            graphics.DrawImageUnscaled(ICSharpCode.WinFormsUI.Controls.Properties.Resources._unchecked, checkboxRect);

                        graphics.EndContainer(container);
                    }
                }
                else 
                {
                    if (image != null)
                    {
                        Point point = this._imageHeight <= cellBounds.Height ? new Point(rectangle.X + this.glyphWidth, cellBounds.Height / 2 - this._imageHeight / 2 + cellBounds.Y) : new Point(rectangle.X + this.glyphWidth, cellBounds.Y + this._imageHeightOffset);
                        GraphicsContainer container = graphics.BeginContainer();
                        graphics.SetClip(cellBounds);
                        graphics.DrawImageUnscaled(image, point);
                        graphics.EndContainer(container);
                    }                     
                }
               
            }

            if (!checkBoxes )
            {
                if (image != null)
                {
                    Point point = this._imageHeight <= cellBounds.Height ? new Point(rectangle.X + this.glyphWidth, cellBounds.Height / 2 - this._imageHeight / 2 + cellBounds.Y) : new Point(rectangle.X + this.glyphWidth, cellBounds.Y + this._imageHeightOffset);
                    GraphicsContainer container = graphics.BeginContainer();
                    graphics.SetClip(cellBounds);
                    graphics.DrawImageUnscaled(image, point);
                    graphics.EndContainer(container);
                }               
            }

            if (owningNode._grid.ShowLines)
            {
                using (Pen pen = new Pen(SystemBrushes.ControlDark, 1f))
                {
                    pen.DashStyle = DashStyle.Dot;
                    bool isLastSibling = owningNode.IsLastSibling;
                    bool isFirstSibling = owningNode.IsFirstSibling;
                    if (owningNode.Level == 1)
                    {
                        if (isFirstSibling && isLastSibling)
                            graphics.DrawLine(pen, rectangle.X + 4, cellBounds.Top + cellBounds.Height / 2, rectangle.Right, cellBounds.Top + cellBounds.Height / 2);
                        else if (isLastSibling)
                        {
                            graphics.DrawLine(pen, rectangle.X + 4, cellBounds.Top + cellBounds.Height / 2, rectangle.Right, cellBounds.Top + cellBounds.Height / 2);
                            graphics.DrawLine(pen, rectangle.X + 4, cellBounds.Top, rectangle.X + 4, cellBounds.Top + cellBounds.Height / 2);
                        }
                        else if (isFirstSibling)
                        {
                            graphics.DrawLine(pen, rectangle.X + 4, cellBounds.Top + cellBounds.Height / 2, rectangle.Right, cellBounds.Top + cellBounds.Height / 2);
                            graphics.DrawLine(pen, rectangle.X + 4, cellBounds.Top + cellBounds.Height / 2, rectangle.X + 4, cellBounds.Bottom);
                        }
                        else
                        {
                            graphics.DrawLine(pen, rectangle.X + 4, cellBounds.Top + cellBounds.Height / 2, rectangle.Right, cellBounds.Top + cellBounds.Height / 2);
                            graphics.DrawLine(pen, rectangle.X + 4, cellBounds.Top, rectangle.X + 4, cellBounds.Bottom);
                        }
                    }
                    else
                    {
                        if (isLastSibling)
                        {
                            graphics.DrawLine(pen, rectangle.X + 4, cellBounds.Top + cellBounds.Height / 2, rectangle.Right, cellBounds.Top + cellBounds.Height / 2);
                            graphics.DrawLine(pen, rectangle.X + 4, cellBounds.Top, rectangle.X + 4, cellBounds.Top + cellBounds.Height / 2);
                        }
                        else
                        {
                            graphics.DrawLine(pen, rectangle.X + 4, cellBounds.Top + cellBounds.Height / 2, rectangle.Right, cellBounds.Top + cellBounds.Height / 2);
                            graphics.DrawLine(pen, rectangle.X + 4, cellBounds.Top, rectangle.X + 4, cellBounds.Bottom);
                        }
                        TreeGridNode parent = owningNode.Parent;
                        int num2 = rectangle.X + 4 - 20;
                        while (!parent.IsRoot)
                        {
                            if (parent.HasChildren && !parent.IsLastSibling)
                                graphics.DrawLine(pen, num2, cellBounds.Top, num2, cellBounds.Bottom);
                            parent = parent.Parent;
                            num2 -= 20;
                        }
                    }
                }
            }

            if (!owningNode.HasChildren && !owningNode._grid.VirtualNodes)
                return;
            if (owningNode.IsExpanded)
                owningNode._grid.rOpen.DrawBackground((IDeviceContext)graphics, new Rectangle(rectangle.X, rectangle.Y + rectangle.Height / 2 - 4, 10, 10));
            else
                owningNode._grid.rClosed.DrawBackground((IDeviceContext)graphics, new Rectangle(rectangle.X, rectangle.Y + rectangle.Height / 2 - 4, 10, 10));
        
        }

        protected override void OnMouseUp(DataGridViewCellMouseEventArgs e)
        {
            base.OnMouseUp(e);
            TreeGridNode owningNode = this.OwningNode;
            if (owningNode == null)
                return;
            owningNode._grid._inExpandCollapseMouseCapture = false;
        }

        protected override void OnMouseDown(DataGridViewCellMouseEventArgs e)
        {
            if (e.Location.X > this.InheritedStyle.Padding.Left)
            {
                base.OnMouseDown(e);
            }           
            else
            {
                TreeGridNode owningNode = this.OwningNode;
                if (owningNode != null)
                {
                    if (owningNode._grid.CheckBoxes && Checkbox )
                    {
                        Rectangle cellBounds = owningNode._grid.GetCellDisplayRectangle(this.ColumnIndex, this.RowIndex, true);
                        int x = cellBounds.X + this.GlyphMargin - (this._imageWidth - 2) / 2;
                        int y = cellBounds.Height / 2 - (this._imageHeight - 2) / 2 + cellBounds.Y;
                        Rectangle checkboxRect = new Rectangle(x, y, (this._imageWidth - 2), (this._imageHeight - 2));
                   
                        if (e.Location.X > checkboxRect.X)
                        {
                            if (e.Location.X < checkboxRect.X + checkboxRect.Width - 4)
                            {
                                if (this.IsChecked)
                                {
                                    this.IsChecked = false;
                                }
                                else
                                {
                                    this.IsChecked = true;
                                }

                                owningNode._grid.CheckedNode(owningNode);
                            }

                            return;
                        }
                    }

                    owningNode._grid._inExpandCollapseMouseCapture = true;
                    if (owningNode.IsExpanded)
                        owningNode.Collapse();
                    else
                        owningNode.Expand();
                  
                }
            }
        }

    }
}
